package com.zmj.sy.mom.srv.aps.service;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.zmj.sy.mom.srv.aps.bean.entity.mes.Part;
import com.zmj.sy.mom.srv.aps.bean.entity.mes.WorkDetailTask;
import com.zmj.sy.mom.srv.aps.bean.entity.mes.WorkRecord;
import com.zmj.sy.mom.srv.aps.bean.entity.order.ApsWorkDetail;
import com.zmj.sy.mom.srv.aps.bean.entity.order.OrderBom;
import com.zmj.sy.mom.srv.aps.bean.vo.base.BaseListResVo;
import com.zmj.sy.mom.srv.aps.bean.vo.part.PartInfoEditReqVo;
import com.zmj.sy.mom.srv.aps.bean.vo.part.PartInfoReqVo;
import com.zmj.sy.mom.srv.aps.bean.vo.part.PartInfoResVo;
import com.zmj.sy.mom.srv.aps.config.ProjectConfig;
import com.zmj.sy.mom.srv.aps.mapper.*;
import com.zmj.sy.mom.srv.aps.utils.NameEqualsUtils;
import com.zmj.sy.mom.srv.aps.utils.WorkshopProp;
import lombok.RequiredArgsConstructor;
import org.apache.commons.lang.StringUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import org.springframework.util.ObjectUtils;

import java.math.BigDecimal;
import java.time.LocalDate;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

@RequiredArgsConstructor
@Service
public class PartService {

    private final OrderBomMapper orderBomMapper;
    private final ApsWorkDetailMapper apsWorkDetailMapper;
    private final WorkDetailTaskMapper workDetailTaskMapper;
    private final PartMapper partMapper;
    private final ProjectConfig projectConfig;
    private final WorkRecordMapper workRecordMapper;
    public Part getPart(String constructNo,String plmid, String phaseCode) {
        return this.getPart(null, constructNo, plmid, phaseCode, null);
    }

    /**
     * @param partType 1:板件 2:零件
     * @param constructNo  施工号
     * @param plmid
     * @param phaseCode  工序号
     * @param prePhaseCode   前道工序
     * @return
     */
    public Part getPart(Integer partType, String constructNo, String plmid, String phaseCode, String prePhaseCode) {
        LambdaQueryWrapper<Part> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(Part::getPlmId, plmid);
        if (StringUtils.isNotBlank(constructNo)) {
            queryWrapper.eq(Part::getConstructNo, constructNo);
        }
        if (StringUtils.isNotBlank(phaseCode)) {
            queryWrapper.eq(Part::getPhaseCode, phaseCode);
        }
        if (partType != null) {
            queryWrapper.eq(Part::getPartType, partType);
        }
        if (StringUtils.isNotBlank(prePhaseCode)) {
            queryWrapper.eq(Part::getPrePhaseCode, prePhaseCode);
        }
        queryWrapper.last("limit 1");
        Part part = partMapper.selectOne(queryWrapper);
      /*  if (ObjectUtils.isEmpty(part) && StringUtils.isNotBlank(constructNo)) {
            queryWrapper = new LambdaQueryWrapper<>();
            queryWrapper.eq(Part::getPlmId, plmid);
            if (StringUtils.isNotBlank(phaseCode)) {
                queryWrapper.eq(Part::getPhaseCode, phaseCode);
            }
            if (partType != null) {
                queryWrapper.eq(Part::getPartType, partType);
            }
            if (StringUtils.isNotBlank(prePhaseCode)) {
                queryWrapper.eq(Part::getPrePhaseCode, prePhaseCode);
            }
            queryWrapper.last("limit 1");
            part = partMapper.selectOne(queryWrapper);
        }*/
        return part;
    }

    public Part getPart(int partType, String plateCode) {
        return this.getPart(partType, null,plateCode, null, null);
    }

    public PartInfoResVo info(PartInfoReqVo reqVo) {
        List<PartInfoResVo> partInfo = partMapper.selectPartInfoResVo(reqVo.getPalletCode()).stream().filter(vo -> StringUtils.isNotBlank(vo.getPlmid())).collect(Collectors.toList());
        for (PartInfoResVo vo : partInfo) {
            vo.setPartPath(String.format(projectConfig.getUrlPre(), vo.getPlmid(), vo.getPartPath()));
        }

        if (CollectionUtils.isEmpty(partInfo)) {
            return null;
        } else {

            PartInfoResVo vo = partInfo.get(0);
            if (WorkshopProp.KJ_PHASE_CODE.equals(vo.getNextNxphase())) {
                OrderBom orderBom = orderBomMapper.lambdaQuery().eq(OrderBom::getPlmId, vo.getPlmid()).last(" limit 1 ").one();
                if (orderBom != null) {
                    OrderBom orderBomP = orderBomMapper.lambdaQuery().eq(OrderBom::getId, orderBom.getPid()).last(" limit 1 ").one();
                    if (orderBomP != null && NameEqualsUtils.equals(orderBomP.getMaterName())) {
                        ApsWorkDetail apsWorkDetail = apsWorkDetailMapper.lambdaQuery().eq(ApsWorkDetail::getMaterNo, orderBomP.getPlmId()).orderByAsc(ApsWorkDetail::getPhaseSeq).last(" limit 1 ").one();
                        if (apsWorkDetail != null) {
                            vo.setNextNxphase(apsWorkDetail.getPhaseCode());
                            vo.setNextGroupNumber(apsWorkDetail.getGroupCode());
                        }
                    }
                }

            }
            return vo;
        }
    }

    public List<PartInfoResVo> palletpat(PartInfoReqVo reqVo) {
        List<PartInfoResVo> partInfos = partMapper.selectPartInfoResVo(reqVo.getPalletCode()).stream().filter(vo -> StringUtils.isNotBlank(vo.getPlmid())).collect(Collectors.toList());
        if(CollectionUtils.isEmpty(partInfos)){
            return  null;
        }
        for (PartInfoResVo vo : partInfos) {
            vo.setPartPath(String.format(projectConfig.getUrlPre(), vo.getPlmid(), vo.getPartPath()));
            if (WorkshopProp.KJ_PHASE_CODE.equals(vo.getNextNxphase())) {
                OrderBom orderBom = orderBomMapper.lambdaQuery().eq(OrderBom::getPlmId, vo.getPlmid()).last(" limit 1 ").one();
                if (orderBom != null) {
                    OrderBom orderBomP = orderBomMapper.lambdaQuery().eq(OrderBom::getId, orderBom.getPid()).last(" limit 1 ").one();
                    if (orderBomP != null && NameEqualsUtils.equals(orderBomP.getMaterName())) {
                        ApsWorkDetail apsWorkDetail = apsWorkDetailMapper.lambdaQuery().eq(ApsWorkDetail::getMaterNo, orderBomP.getPlmId()).orderByAsc(ApsWorkDetail::getPhaseSeq).last(" limit 1 ").one();
                        if (apsWorkDetail != null) {
                            vo.setNextNxphase(apsWorkDetail.getPhaseCode());
                            vo.setNextGroupNumber(apsWorkDetail.getGroupCode());
                        }

                    }
                }

            }

        }
        return partInfos;

    }

    public BaseListResVo<ApsWorkDetail> checkDetailQuantity() {
        List<ApsWorkDetail> list = new ArrayList<>();
        List<ApsWorkDetail> apsWorkDetailList = apsWorkDetailMapper.lambdaQuery()
                .in(ApsWorkDetail::getPhaseCode, projectConfig.getCuttingProcess())
                .eq(ApsWorkDetail::getType, 2)
                .gt(ApsWorkDetail::getFinishCount, 0)
                .ge(ApsWorkDetail::getCreateDateTime, "2024-12-20 21:32:22")
                .list();
        List<ApsWorkDetail> apsWorkDetailListWOList = apsWorkDetailMapper.lambdaQuery()
                .in(ApsWorkDetail::getApsWorkOrderId, apsWorkDetailList.stream().map(ApsWorkDetail::getApsWorkOrderId).collect(Collectors.toList()))
                .list();
        Map<Integer, List<ApsWorkDetail>> apsWorkDetailListWOMap = apsWorkDetailListWOList.stream().collect(Collectors.groupingBy(ApsWorkDetail::getApsWorkOrderId));
        for (Integer i : apsWorkDetailListWOMap.keySet()) {
            List<ApsWorkDetail> details = apsWorkDetailListWOMap.get(i);
            Map<String, ApsWorkDetail> detailsMap = details.stream().collect(Collectors.toMap(ApsWorkDetail::getPhaseCode, a -> a));
            ApsWorkDetail lL = detailsMap.get("LL");
            ApsWorkDetail yC = detailsMap.get("YC");
            ApsWorkDetail qG = detailsMap.get("JG") != null ? detailsMap.get("JG") : detailsMap.get("HG");
            if (lL.getFinishCount().compareTo(qG.getFinishCount()) < 0) {
                lL.setFinishCount(qG.getFinishCount());
                lL.setStatus(4);
//                apsWorkDetailMapper.updateById(lL);
                list.add(lL);
            }
            if (yC.getFinishCount().compareTo(qG.getFinishCount()) < 0) {
                yC.setFinishCount(qG.getFinishCount());
                yC.setStatus(4);
//                apsWorkDetailMapper.updateById(yC);
                list.add(yC);
            }
        }
        return BaseListResVo.of(list, ApsWorkDetail.class);
    }

    public BaseListResVo<WorkRecord> fixPartBZPhase() {
        // 查询需要修改的报工记录
        List<WorkRecord> workRecordList = workRecordMapper.lambdaQuery()
                .eq(WorkRecord::getPhaseCode, "BZ")
                .eq(WorkRecord::getPlmid, "ZT01-39-9_N_170")
                .eq(WorkRecord::getGroupNumber, "2-1_LZPD_00")
                .list();
        // 查询需要修改的计划
        List<ApsWorkDetail> apsWorkDetailList = apsWorkDetailMapper.lambdaQuery()
                .in(ApsWorkDetail::getId, workRecordList.stream().map(WorkRecord::getApsWorkDetailId).collect(Collectors.toList()))
                .list();
        Map<Integer, ApsWorkDetail> apsWorkDetailMap = apsWorkDetailList.stream().collect(Collectors.toMap(ApsWorkDetail::getId, a -> a));
        // 查询需要修改的任务
        List<WorkDetailTask> workDetailTaskList = workDetailTaskMapper.lambdaQuery()
                .in(WorkDetailTask::getId, workRecordList.stream().map(WorkRecord::getOperationId).collect(Collectors.toList()))
                .list();
        Map<Integer, WorkDetailTask> workDetailTaskMap = workDetailTaskList.stream().collect(Collectors.toMap(WorkDetailTask::getId, a -> a));
        for (WorkRecord workRecord : workRecordList) {
            ApsWorkDetail detail = apsWorkDetailMap.get(workRecord.getApsWorkDetailId());
            WorkDetailTask task = workDetailTaskMap.get(workRecord.getOperationId());

            detail.setFinishCount(detail.getFinishCount().subtract(BigDecimal.valueOf(workRecord.getSuccessCount())));
            detail.setStatus(3);

            task.setFinishCount(task.getFinishCount() - workRecord.getSuccessCount());
            task.setStatus(2);

            apsWorkDetailMapper.updateById(detail);
            workDetailTaskMapper.updateById(task);
        }
        return BaseListResVo.of(workRecordList, WorkRecord.class);
    }

    public void updateById(Part nextPart) {
        partMapper.updateById(nextPart);
    }
    public void creatPart(Part one) {
        partMapper.insert(one);
    }

    public void clearPlate(String plateCode) {
        List<Part> ps = partMapper.lambdaQuery()
                .eq(Part::getPlmId, plateCode)
//                .eq(Part::getPhaseCode, WorkshopProp.FJ_PHASE_CODE)
                .eq(Part::getPartType, 1)
                .list();
        if (!CollectionUtils.isEmpty(ps)) {
            for (Part p : ps){
                partMapper.deleteReal(p.getId());
            }
        }
    }
    @Transactional
    public void edit(PartInfoEditReqVo reqVo) {

        Part old = partMapper.lambdaQuery().eq(Part::getId, reqVo.getId()).eq(Part::getPlmId, reqVo.getPlmId()).one();
        Part one = partMapper.lambdaQuery().eq(Part::getConstructNo, reqVo.getCuconstructNo().trim())
                .eq(Part::getPhaseCode, old.getPhaseCode())
                .eq(Part::getPlmId, reqVo.getPlmId()).one();
        if(!ObjectUtils.isEmpty(one)){
            partMapper.deleteById(old.getId());
            partMapper.updateCount(one.getId(),old.getPartCount(),old.getFailCount());
        }
        old.setConstructNo(reqVo.getCuconstructNo().trim());
        partMapper.updateById(old);

    }

    public void deletePart() {
        LocalDate now = LocalDate.now();

        QueryWrapper<Part> qwd = new QueryWrapper<>();
        qwd.and(qw -> qw
                .eq("p.part_count", 0)
                .le("p.modify_date_time", now.minusWeeks(1))
                .or()
                .eq("p.phase_code", "KJ")
                .eq("p.pre_phase_code", "PT")
                .le("p.modify_date_time", now.minusMonths(1))
        );
        partMapper.deletePartZero(qwd);

        /*QueryWrapper<Part> qws = new QueryWrapper<>();
        qws.ge("o.order_status", 9);
        qws.le("p.modify_date_time", now.minusWeeks(1));
        List<Integer> ids = partMapper.selectPartZero(qws);
        for (Integer id : ids) {
//            partMapper.deleteReal(id);
            partMapper.deleteById(id);
        }*/
    }

}
